package com.example.iorder.reservation;

import java.util.ArrayList;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ExpandableListView;
import android.widget.ImageButton;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;

import com.example.domain.Menu;
import com.example.domain.MenuItem;
import com.example.domain.OrderedMenuItem;
import com.example.iorder.R;
import com.example.iorder.config.Config;
import com.example.iorder.payment.SampleActivity;
import com.example.iorder.util.HTTPClient;
import com.example.iorder.util.TextFormatter;

public class SelectMenuItem extends Activity implements Runnable {
	private ProgressDialog progress;
	private int restaurantId = 0;
	protected MenuListAdapter adapter;
	private ExpandableListView listView;
	private TextView priceView;

	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.reservation_select_menu_item);

		// Show loading indicator
		progress = new ProgressDialog(this);
		startLoadingIndicator();

		// Get the selected restaurant id
		Bundle reservationInfo = getIntent().getExtras();
		restaurantId = reservationInfo.getInt(getResources().getString(R.string.key_restaurant_id));
		
		View viewWithId = findViewById(R.id.menuListview);
		listView = (ExpandableListView) viewWithId;
		priceView = (TextView) findViewById(R.id.totalPrice);
		
		// Initialize the adapter with black groups and children
		// We will be adding the children on a thread, and then update the listview
		adapter = new MenuListAdapter(this, new ArrayList<Menu>(), new ArrayList<ArrayList<OrderedMenuItem>>());
        listView.setAdapter(adapter);
        
        updateTotalPrice();
        
        //restaurantId = getIntent().getExtras().getInt(getResources().getString(R.string.key_restaurant_id));
        Thread thread = new Thread(this);
        thread.start();
        
        adapter.notifyDataSetChanged();
	}
	
	@Override
	public void run() {
		Message msg = new Message();
		String path = "";
		HTTPClient httpClient = null;
		String searchResult = "";

		try {
			// Get the menus
			path = Config.URL_RESTAURANTS + restaurantId + Config.URL_MENUS;
			httpClient = new HTTPClient(getBaseContext());
			searchResult = httpClient.sendGETRequest(Config.IORDER_SERVER, path);
			
			String newData = msg.getData().getString("restaurantMenus");
			JSONArray records = null;
			ArrayList<Menu> list = new ArrayList<Menu>();

			try {
				JSONObject jsonObject = new JSONObject(searchResult);
				if (jsonObject.has("data") && jsonObject.has("msg")	&& jsonObject.has("status")) {
					// Connection to server was successful and data was received
					if (jsonObject.get("status").toString().equals("200")) {
						records = jsonObject.getJSONArray("data");

						// Convert data into a list of MenuItems
						for (int i = 0; i < records.length(); i++) {
							try {
								JSONObject row = records.getJSONObject(i);
								// Create a list of menus
								if (row != null) {
									String idString = row.optString("ID");
									String title = row.optString("Title");
									int id = Integer.parseInt(idString);

									Menu newItem = new Menu(id, title);
									list.add(newItem);
									adapter.addMenu(newItem);
								}
							} catch (Exception e) {
							}
						}

						// Update the GUI
						if (list.size() > 0) {
							menuHandler.sendEmptyMessage(1);
							//adapter.notifyDataSetChanged();
						} else {
							// Show empty results message
						}
					} else {
						Toast.makeText(getBaseContext(), "Backend server error no : " + jsonObject.get("status").toString(),
								Toast.LENGTH_SHORT).show();
					}
				} else {
					Toast.makeText(getBaseContext(), "Faulty backend server response!", Toast.LENGTH_SHORT).show();
				}
			} catch (JSONException jsnE) {
				String errorMessage = "JSON Error: " + jsnE.getMessage();
				if (newData.equals("Error: No network")) {
					errorMessage = getResources().getString(R.string.no_network_connection);
				}
				Toast.makeText(getBaseContext(), errorMessage,Toast.LENGTH_LONG).show();
			} catch (Exception e) {
				Toast.makeText(getBaseContext(), "Error: " + e.getMessage(), Toast.LENGTH_SHORT).show();
			}
			
			// Get the menu items
			adapter.clearChildrenData();
			for (Menu menu : list) {
				int menuID = menu.getId();
				msg = new Message();
				path = "";
				httpClient = null;
				searchResult = "";
	
				try {
					path = Config.URL_RESTAURANTS + restaurantId + Config.URL_MENUS + menuID + Config.URL_MENU_ITEMS;
					httpClient = new HTTPClient(getBaseContext());
					searchResult = httpClient.sendGETRequest(Config.IORDER_SERVER, path);
					
					newData = msg.getData().getString("menuItems");
					records = null;
					ArrayList<MenuItem> mlist = new ArrayList<MenuItem>();

					try {
						JSONObject jsonObject = new JSONObject(searchResult);
						if (jsonObject.has("data") && jsonObject.has("msg")	&& jsonObject.has("status")) {
							// Connection to server was successful and data was received
							if (jsonObject.get("status").toString().equals("200")) {
								records = jsonObject.getJSONArray("data");

								// Convert data into a list of MenuItems
								for (int i = 0; i < records.length(); i++) {
									try {
										JSONObject row = records.getJSONObject(i);
										if (row != null) {
											String idString = row.optString("ID");
											String menuIdString = row.optString("MenuID");
											String title = row.optString("Title");
											String description = row.optString("Description");
											String itemType = row.optString("ItemType");
											String priceString = row.optString("Price");
											int id = Integer.parseInt(idString);
											int menuId = Integer.parseInt(menuIdString);
											double price = priceString.length() > 0 ? Double.parseDouble(priceString) : 0.0;

											MenuItem newItem = new MenuItem(id, menuId, title, description, itemType, price);
											mlist.add(newItem);
										}
									} catch (Exception e) {
										Log.e("Parsing error", "An error occured while parsing the list of menu items:" + e.getMessage());
									}
								}

								// Update the GUI
								if (mlist.size() > 0) {
									ArrayList<OrderedMenuItem> orderedMenuItemsList = new ArrayList<OrderedMenuItem>();
									for (MenuItem mi : mlist) {
										OrderedMenuItem omi = new OrderedMenuItem(mi);
										adapter.addMenuItem(omi);
										orderedMenuItemsList.add(omi);
									}
									menuHandler.sendEmptyMessage(2);
								} else {
									break;
								}
							} else {
								Toast.makeText(getBaseContext(), "Backend server error no : " + jsonObject.get("status").toString(),
										Toast.LENGTH_SHORT).show();
							}
						} else {
							Toast.makeText(getBaseContext(), "Faulty backend server response!", Toast.LENGTH_SHORT).show();
						}
					} catch (JSONException jsnE) {
						String errorMessage = "JSON Error: " + jsnE.getMessage();
						if (newData.equals("Error: No network")) {
							errorMessage = getResources().getString(R.string.no_network_connection);
						}
						Toast.makeText(getBaseContext(), errorMessage,Toast.LENGTH_LONG).show();
					} catch (Exception e) {
						Toast.makeText(getBaseContext(), "Error: " + e.getMessage(), Toast.LENGTH_SHORT).show();
					}
	
//					msg.getData().putString("menuItems", searchResult);
//					menuItemHandler.sendMessage(msg);
				} catch (Exception e) {
					msg.getData().putString("exception", e.toString());
				}
			}
		} catch (Exception e) {
			stopLoadingIndicator();
			String errorMessage = getResources().getString(R.string.no_network_connection);
			Toast.makeText(getBaseContext(), errorMessage,Toast.LENGTH_LONG).show();
			Log.e("Loading menu", "Problem while loading menus and menu items: " + e.getMessage());
		}
	}

	@SuppressLint("HandlerLeak")
	private Handler menuHandler = new Handler() {
		public void handleMessage(Message msg) {
			adapter.notifyDataSetChanged();
			if (msg.what == 2)
				stopLoadingIndicator();
		}
	};
	
	public void reduceAmountOfSelectedItem(View view) {
		ImageButton clickedButton = (ImageButton) view;
		View parentView = (View) clickedButton.getParent();
		if (parentView instanceof RelativeLayout) {
			int menuId = parentView.getTag(R.id.menuID) != null ? (Integer) parentView.getTag(R.id.menuID) : -1;
			int menuItemId = parentView.getTag(R.id.menuItemID) != null ? (Integer) parentView.getTag(R.id.menuItemID) : -1;
			
			// Retrieval of menu id and menu item id was successful
			if (menuId != -1 && menuItemId != -1) {
				adapter.decreaseAmountOfOrderedMenuItem(menuId, menuItemId);
			}
			
			// Update the total price
			updateTotalPrice();
		} else
			Toast.makeText(this, "An error occured while attempting to remove the selected item", Toast.LENGTH_SHORT).show();
	}
	
	public void increaseAmountOfSelectedItem(View view) {
		ImageButton clickedButton = (ImageButton) view;
		View parentView = (View) clickedButton.getParent();
		if (parentView instanceof RelativeLayout) {
			int menuId = parentView.getTag(R.id.menuID) != null ? (Integer) parentView.getTag(R.id.menuID) : -1;
			int menuItemId = parentView.getTag(R.id.menuItemID) != null ? (Integer) parentView.getTag(R.id.menuItemID) : -1;
			
			// Retrieval of menu id and menu item id was successful
			if (menuId != -1 && menuItemId != -1) {
				adapter.increaseAmountOfOrderedMenuItem(menuId, menuItemId);
			}
			
			// Update the total price
			updateTotalPrice();
		} else
			Toast.makeText(this, "An error occured while attempting to add the selected item", Toast.LENGTH_SHORT).show();
	}
	
	private void updateTotalPrice() {
		double newTotalPrice = adapter.getCurrentTotalPrice();
		String formattedPrice = TextFormatter.formatStringForTotalPrice(this, newTotalPrice);
		priceView.setText(formattedPrice);
		
		Button continueButton = (Button) findViewById(R.id.skipMenu);
		if (newTotalPrice > 0) {
			continueButton.setText(getResources().getString(R.string.lbl_continue));
		} else {
			continueButton.setText(getResources().getString(R.string.lbl_skip_menu));
		}
	}
	
	private void startLoadingIndicator() {
		progress.setTitle(getResources().getString(R.string.loading_title));
		progress.setMessage(getResources().getString(R.string.loading_message));
		progress.show();
	}
	
	private void stopLoadingIndicator() {
		progress.dismiss();
	}
	
	public void onContinueClick(View view) {
		double newTotalPrice = adapter.getCurrentTotalPrice();
		
		if (newTotalPrice > 0) {
			Intent intent = new Intent(this, SampleActivity.class);
			Bundle extraInfo = new Bundle(getIntent().getExtras());
			extraInfo.putSerializable("menus", adapter.getAllGroups());
			extraInfo.putSerializable("menuItems", adapter.getAllChildren());
			intent.putExtras(extraInfo);
			startActivity(intent);
		} else {
			Intent intent = new Intent(this, FinalOverview.class);
			Bundle extraInfo = new Bundle(getIntent().getExtras());
			extraInfo.putSerializable("menus", adapter.getAllGroups());
			extraInfo.putSerializable("menuItems", adapter.getAllChildren());
			intent.putExtras(extraInfo);
			startActivity(intent);
		}
	}
}
